# Identifiers and Time
This note covers `src/ids.rs` and `src/clock.rs`.
## `LocId`
**Defined in:** `src/ids.rs`
A newtype over `u64` representing a caller-assigned location identifier.
### Role
- primary key into the location table,
- stable handle used by all event types,
- deliberately opaque to the engine.
### Why it matters
Using a newtype prevents mixing location ids with action ids at compile time while remaining zero-cost at runtime.
### Relationships
- used by [[Modules/Events#StateUpdate]], [[Modules/Events#ActionIngest]], and [[Modules/Events#Trigger]],
- keys the [[Modules/Location State#LocationTable]].
## `ActionId`
**Defined in:** `src/ids.rs`
A newtype over `u64` representing a caller-assigned action identifier.
### Role
- identifies one registered action within a location,
- echoed in [[Modules/Engine and Decision#Outcome]].
### Relationships
- enters through [[Modules/Events#ActionIngest]],
- stored in [[Modules/Location State#ActionEntry]],
- copied into [[Modules/Scoring Core#Candidate]].
## `KindId`
**Defined in:** `src/ids.rs`
A newtype over `u16` representing the interned id of a kind name.
### Role
- compact runtime handle for kind lookup,
- index into the schema's kind table,
- used for slot resolution.
### Relationships
- produced by [[Modules/Schema#SchemaBuilder]],
- carried by [[Modules/Events#KindRef]] and [[Modules/Location State#LocationDef]].
## `AttrId`
**Defined in:** `src/ids.rs`
A newtype over `u16` representing the interned id of an attribute name.
### Role
- compact runtime handle for one schema attribute,
- used to resolve a [[Modules/Schema#Slot]].
### Relationships
- carried inside [[Modules/Events#AttrSet]],
- resolved through [[Modules/Schema#SlotLayout]].
## `UnixTime`
**Defined in:** `src/ids.rs`
A type alias for `i64` meaning seconds since the Unix epoch.
### Role
- action validity windows use it for `start` and `end`,
- clocks return it,
- expiry logic compares actions against it.
## `Clock`
**Defined in:** `src/clock.rs`
A trait with one method: `now() -> UnixTime`.
### Role
This is the engine's time source abstraction. It keeps expiry deterministic under tests and lets callers inject different time strategies.
### Relationships
- stored in [[Modules/Engine and Decision#EngineConfig]],
- used by `Engine::ingest_trigger`.
## `SystemClock`
**Defined in:** `src/clock.rs`
The production implementation of [[#Clock]].
### Behavior
- wraps `SystemTime::now()`,
- converts to Unix seconds,
- clamps pathological pre-epoch values to `0` instead of panicking.
### Why that clamp exists
Expiry logic depends on a usable timestamp. If the system clock is broken, returning `0` is safer than crashing the engine.
## `TestClock`
**Defined in:** `src/clock.rs`
A test-oriented clock backed by `AtomicI64`.
### API
- `TestClock::at(t)` creates a clock at a chosen time and returns it in `Arc<Self>`.
- `advance(secs)` moves time forward.
- `set(t)` forces an exact time.
### Role
This type is the foundation for deterministic expiry tests and scenario tests.
### Relationships
- used in `tests/integration_expiry.rs`, `tests/integration_metrics.rs`, and the scenario test added for this wiki.
## Design summary
The id types and clock abstraction are small, but they are foundational:
- ids make the rest of the API type-safe,
- the clock makes the engine predictable and testable.